package com.platform.modules.mall.location.utils;

import com.platform.common.exception.BusinessException;
import com.platform.modules.mall.location.Location;

import java.util.Map;

/**
 * 经纬度工具类
 * @author
 */
public class LocationUtil {

    private static double EARTH_RADIUS = 6378.137;
    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 通过经纬度获取距离(单位：米)
     * @param lat1
     * @param lng1
     * @param lat2
     * @param lng2
     * @return 距离 m
     */
    public static double getDistance(double lat1, double lng1, double lat2,double lng2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000d) / 10000d;
        s = s*1000;
        return s;
    }

    /**
     * 根据当前坐标点 返回附近的圆形坐标点
     * @param lat
     * @param lon
     * @param angle 画圆时多少度取一个点 范围[1 - 90]度    值越小精度越高，但消耗性能  推荐 30
     * @param range 范围 单位/公里
     * @return
     */
    public static String getAroundLocations(double lat,double lon,int angle,float range){
        double x,y;
        double latm = 10/getDistance(lat+0.01,lon, lat,lon) * range;
        double lonm = 10/getDistance(lat,lon, lat,lon+0.01) * range;
        int singleLength = 90 / angle;
        Location[] list = new Location[singleLength * 4];
        for (int i = angle,index = singleLength;i < 90 && index > 1;i += angle){
            x = Math.cos(Math.toRadians(i));
            y = Math.sin(Math.toRadians(i));
            list[--index] = new Location(x * lonm + lon,y * latm + lat);
            list[singleLength*2-index] = new Location(x * lonm + lon,lat - y * latm);
            list[singleLength*2+index] = new Location(lon - x * lonm,lat - y * latm);
            list[list.length-index] = new Location(lon - x * lonm,y * latm + lat);
        }
        list[0] = new Location(lon, lat + latm);
        list[singleLength] = new Location(lonm + lon,lat);
        list[singleLength*2] = new Location(lon,lat - latm);
        list[singleLength*3] = new Location(lon - lonm,lat);
        String round = org.apache.commons.lang.StringUtils.join(list,",")+","+list[0].toString();
        return round;
    }

    /**
     * 初始化查询参数
     */
    public static void initialNearbyParams(Map<String, Object> params){
        // 注意 mysql8.0 以上 配合新的距离计算函数 此处需要换成 （纬度，经度）  旧版本使用 （经度，纬度）
        if(params.get("location") == null){
            throw new BusinessException("获取当前位置出错！!");
        }

        Object range = params.get("range");
        try {
            params.put("location", params.remove("location").toString().replace(","," "));
            String[] location = ((String) params.get("location")).split(" ");
            if(range != null){
                params.put("scope", getAroundLocations(Double.parseDouble(location[0]), Double.parseDouble(location[1]), 30,Float.parseFloat(range.toString())));
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("获取当前位置出错！");
        }
    }

    public static void main(String[] args) {
        System.out.println(getAroundLocations(28.132786,112.987787,30,5));
    }

}
